﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace Shared
{
    public class AppSetting
    {
        private static readonly ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;

        static AppSetting()
        {
        }

        private static T GetNumber<T>(Enum key, T failback_value) where T : struct
        {
            T t = GetNumber<T>(key, null, failback_value);
            return t;
        }

        public static T GetNumber<T>(Enum key, string key_uni_name, T default_value) where T : struct
        {
            T t = default_value;
            string strKey = JoinKey(key, key_uni_name);            
            if (localSettings.Values.TryGetValue(strKey, out object v))
            {
                if (v.GetType() == typeof(T))
                {
                    t = (T)v;
                }
            }
            return t;
        }

        private static T GetObject<T>(Enum key, T failback_value) where T : class
        {
            T t = GetObject<T>(key, null, failback_value);
            return t;
        }

        public static T GetObject<T>(Enum key, string key_uni_name, T default_value) where T : class
        {
            T t = default_value;
            string strKey = JoinKey(key, key_uni_name);            
            if (localSettings.Values.TryGetValue(strKey, out object v))
            {
                if (v != null && v.GetType() == typeof(T))
                {
                    t = v as T;
                }
            }
            return t;
        }

        public static UInt64 GetUInt64(Enum key, UInt64 default_value = default)
        {
            return GetNumber<UInt64>(key, default_value);
        }

        public static Int64 GetInt64(Enum key, Int64 default_value = default)
        {
            return GetNumber<Int64>(key, default_value);
        }

        public static Double GetDouble(Enum key, Double default_value = default)
        {
            return GetNumber<Double>(key, default_value);
        }

        public static String GetString(Enum key, String default_value = "")
        {
            return GetObject<String>(key, default_value);
        }

        public static bool GetBoolean(Enum key, bool default_value = default)
        {
            return GetNumber<bool>(key, default_value);
        }

        public static T GetEnum<T>(Enum key, T default_value) where T : struct
        {
            string s = GetString(key);
            T t = s.ToEnum<T>(default_value);
            return t;
        }

        public static void Set<T>(Enum key, string key_uni_name, T v)
        {
            string strKey = JoinKey(key, key_uni_name);
            localSettings.Values[strKey] = v;
        }

        private static void Set<T>(Enum key, T v)
        {
            Set<T>(key, null, v);
        }

        public static void SetUInt64(Enum key, UInt64 v)
        {
            Set<UInt64>(key, v);
        }

        public static void SetInt64(Enum key, Int64 v)
        {
            Set<Int64>(key, v);
        }

        public static void SetDouble(Enum key, Double v)
        {
            Set<Double>(key, v);
        }

        public static void SetString(Enum key, String v)
        {
            Set<String>(key, v);
        }

        public static void SetBoolean(Enum key, Boolean v)
        {
            Set<Boolean>(key, v);
        }

        public static void SetEnum<T>(Enum key, T t) where T : struct
        {
            Set<string>(key, t.ToString());
        }

        private static string JoinKey(Enum key, string key_uni_name)
        {
            string strKey = key.GetType().FullName + "_" + key.ToString();
            if (String.IsNullOrEmpty(key_uni_name) == false)
            {
                strKey = strKey + "_@_" + key_uni_name;
            }
            return strKey;
        }
    }
}
